package psn.kiko.service.business.system;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import psn.kiko.constant.DBConstant;
import psn.kiko.constant.GenderConstant;
import psn.kiko.constant.MessageConstant;
import psn.kiko.context.UserContext;
import psn.kiko.excepion.BaseBusinessException;
import psn.kiko.excepion.UserOperationException;
import psn.kiko.mapper.business.system.UserMapper;
import psn.kiko.pojo.PageResult;
import psn.kiko.pojo.dto.UserDTO;
import psn.kiko.pojo.dto.UserLoginDTO;
import psn.kiko.pojo.entity.system.UserEntity;
import psn.kiko.pojo.vo.AllocateRoleVo;
import psn.kiko.pojo.vo.DelDetailVO;
import psn.kiko.pojo.vo.InterfaceVO;
import psn.kiko.pojo.vo.LabelValue;
import psn.kiko.pojo.vo.UserLoginVO;
import psn.kiko.pojo.vo.UserVO;
import psn.kiko.service.business.associated.UserRoleService;
import psn.kiko.util.encrypt.Tokens;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 2023/10/23 13:57<br>
 * 用户服务
 */
@Service
@Slf4j
public class UserService{
	@Autowired
	UserMapper userMapper;
	@Autowired
	UserRoleService userRoleService;
	@Autowired
	Tokens tokens;
	@Autowired
	OperationService operationService;
	
	/**
	 * 用户登录
	 */
	@Transactional
	public UserLoginVO loginByPasswordAndName(UserLoginDTO userLoginDTO){
		UserEntity user = new UserEntity();
		BeanUtils.copyProperties(userLoginDTO,user);
		UserEntity userInDB = userMapper.select(user);
		//用户不存在
		if(userInDB == null)
			throw new UserOperationException(MessageConstant.USER_NOT_EXIST);
		/*//若用户已登录，且为可编辑的用户
		//		if(userInDB.getLoginStatus() == DBConstant.LOGIN_STATUS&&userInDB.getEditable() == DBConstant.EDITABLE)
		//			throw new UserOperationException(MessageConstant.USER_DUPLICATE_LOGIN);
		//更新用户登录状态为已登录*/
		userMapper.updateLoginStatusById(userInDB.getId(),DBConstant.LOGIN_STATUS);
		
		//用户存在,生成token，并查询UI权限级联视图返回
		String uid = String.valueOf(userInDB.getId());
		String uname = userInDB.getName();
		String token = tokens.generateFrom(uid,uname);
		log.debug("用户:{},token:{}",userInDB.getName(),token);
		// 获取UI权限
		Map<String,Object> uiAuths = operationService.getAvailableUIAuthsOfEditableUser(userInDB);
		UserLoginVO loginVO = UserLoginVO.builder()
				.token(token)
				.uiAuths(uiAuths)
				.build();
		return loginVO;
	}
	
	
	
	/**
	 * 添加用户
	 */
	public Integer addUser(UserDTO userDTO){
		try{
			if(!GenderConstant.getAllGenders().contains(userDTO.getGender()))
				userDTO.setGender(GenderConstant.UNSET);
			if(!DBConstant.getStatuses().contains(userDTO.getEnabled()))
				userDTO.setEnabled(DBConstant.DISABLE);
			
			UserEntity userEntity = new UserEntity();
			BeanUtils.copyProperties(userDTO,userEntity);
			ArrayList<UserEntity> userEntities = new ArrayList<>(1);
			userEntities.add(userEntity);
			return userMapper.insertBatch(userEntities);
		}catch(Exception e){
			e.printStackTrace();
			if(e instanceof DuplicateKeyException){
				throw new BaseBusinessException(MessageConstant.INSERT_DUPLICATE_ROWS);
			}else
				throw new BaseBusinessException(MessageConstant.UNKNOWN_ERROR);
		}
	}
	
	/**
	 * 批量添加用户
	 */
	public Integer addUsers(List<UserDTO> userDTOs){
		ArrayList<UserEntity> userEntities = new ArrayList<>();
		for(UserDTO userDTO: userDTOs){
			UserEntity userEntity = new UserEntity();
			BeanUtils.copyProperties(userDTO,userEntity);
		}
		return userMapper.insertBatch(userEntities);
	}
	
	/**
	 * 根据id删除一批用户
	 * <p style="color:red">并删除中间表数据：用户-角色</p>
	 */
	@Transactional
	public List<DelDetailVO> deleteUsersByIds(List<Integer> userIds){
		//先批量删除 用户-角色 关联表中的数据
		Integer c1 = userRoleService.batchDeleteByUserIds(userIds);
		//删除用户表
		Integer c2 = userMapper.deleteBatchByIds(userIds);
		ArrayList<DelDetailVO> delDetailVOS = new ArrayList<>();
		delDetailVOS.add(new DelDetailVO("删除的用户数量",c2));
		delDetailVOS.add(new DelDetailVO("移除与这批用户关联的角色的数量",c1));
		return delDetailVOS;
	}
	
	/**
	 * 分页获取用户
	 */
	public PageResult selectUsersByPage(UserDTO userDTO,int pageNum,int pageSize){
		UserEntity userEntity = new UserEntity();
		BeanUtils.copyProperties(userDTO,userEntity);
		Page<Object> page = PageHelper.startPage(pageNum,pageSize);
		List<UserVO> list = userMapper.selectList(userEntity);
		return PageResult.builder()
				.total(((int) page.getTotal()))
				.data(list)
				.build();
	}
	
	/**
	 * 根据id批量启用用户
	 */
	public Integer enableUsersByIds(List<Integer> ids){
		return userMapper.updateStatusByIds(ids,DBConstant.ENABLE);
	}
	
	/**
	 * 根据主键批量禁用用户
	 */
	public Integer disableUsersByIds(List<Integer> ids){
		return userMapper.updateStatusByIds(ids,DBConstant.DISABLE);
	}
	
	/**
	 * 获取所有状态
	 */
	public List<Short> getAllStatus(){
		return DBConstant.getStatuses();
	}
	
	/**
	 * 根据主键获取用户
	 */
	public UserEntity getUserById(Integer userId){
		return userMapper.selectById(userId);
	}
	
	/**
	 * 更新用户
	 */
	public Integer updateUser(UserDTO userDTO){
		Short status = userDTO.getEnabled();
		//状态须符合系统规定
		List<Short> validStatuses = DBConstant.getStatuses();
		if(!validStatuses.contains(status)){
			userDTO.setEnabled(DBConstant.DISABLE);
		}
		//性别须符合系统规定
		Short gender = userDTO.getGender();
		List<Short> validGenders = GenderConstant.getAllGenders();
		if(!validGenders.contains(gender)){
			userDTO.setGender(GenderConstant.UNSET);
		}
		UserEntity userEntity = new UserEntity();
		BeanUtils.copyProperties(userDTO,userEntity);
		return userMapper.updateById(userEntity);
	}
	
	/**
	 * 根据主键获取用户已分配的角色列表
	 */
	public List<AllocateRoleVo> getAllocatedRolesByUserId(Integer userId){
		return userRoleService.selectAllocatedRolesByOfUserId(userId);
	}
	
	/**
	 * 根据主键获取用户还未分配到的角色列表
	 */
	public List<AllocateRoleVo> getUnallocatedRolesByUserId(Integer userId){
		return userRoleService.getUnallocatedRolesByUserId(userId);
	}
	
	/**
	 * 给用户批量分配角色
	 */
	public Integer batchAllocateRolesToUser(List<Integer> roleIds,Integer userId){
		return userRoleService.allocateOneUserToMultiRoles(userId,roleIds);
	}
	
	/**
	 * 删除用户的一批角色
	 */
	public Integer batchUnAllocateRolesToUser(List<Integer> roleIds,Integer userId){
		return userRoleService.batchDeleteByUserIdAndRoleIds(userId,roleIds);
	}
	
	/**
	 * 启用用户的一批角色
	 */
	public Integer enableRolesOfUser(List<Integer> roleIds,Integer userId){
		return userRoleService.baEnableByUserId(roleIds,userId);
	}
	
	/**
	 * 禁用用户的一批角色
	 */
	public Integer disableRolesOfUser(List<Integer> roleIds,Integer userId){
		return userRoleService.batchDisableByUserId(roleIds,userId);
	}
	
	/**
	 * 获取所有用户性别
	 */
	public List<LabelValue> getAllGenders(){
		return GenderConstant.getGendersWithLabel();
	}
	
	/**
	 * 获取所有状态可用值
	 */
	public List<LabelValue> getStatusesWithLabel(){
		return DBConstant.getStatusesWithLabel();
	}
	
	/**
	 * 获取用户已分配的全部接口
	 */
	public List<InterfaceVO> getAllAllocatedApisOfUser(Integer userId){
		return userRoleService.getAllAllocatedApisOfUser(userId);
	}
	
	/**
	 * 用户退出登录
	 */
	public Integer logoutById(Integer userId){
		//若用户id不是当前登录用户的id，直接抛业务异常
		if(UserContext.getUserId() != userId)
			throw new UserOperationException(MessageConstant.ACCOUNT_WAS_NOT_OWNED_BY_LOGIN_USER);
		return userMapper.updateLoginStatusById(userId,DBConstant.LOGOUT_STATUS);
	}
}
